package com.syh.jn.scm.domain.supplier.entity.finance;

import cn.redscarf.commons.spring.SpringContextUtils;
import cn.redscarf.commons.util.validator.ValidationUtils;
import cn.redscarf.commons.wrapper.Restrictions;
import cn.redscarf.commons.wrapper.Wrapper;
import com.syh.core.ddd.domain.AbstractSimpleAggregate;
import com.syh.jn.scm.domain.supplier.entity.purchase.PurchaseOrder;
import com.syh.jn.scm.domain.supplier.entity.sale.SaleOrder;
import com.syh.jn.scm.domain.supplier.repository.finance.OrderExpensesBillRepository;
import com.syh.jn.scm.domain.supplier.repository.purchase.PurchaseOrderReadRepository;
import com.syh.jn.scm.domain.supplier.repository.sale.SaleOrderReadRepository;
import com.syh.jn.scm.dto.supplier.finance.orderExpensesBill.OrderExpensesBillMto;
import com.syh.jn.scm.dto.supplier.finance.orderExpensesBill.OrderExpensesBillSto;
import com.syh.jn.scm.exception.BusinessException;
import com.syh.jn.scm.service.api.supplier.finance.enums.OrderExpensesBillEnums;
import com.syh.jn.scm.service.api.supplier.purchase.enums.PurchaseOrderEnums;
import com.syh.jn.scm.service.api.supplier.sale.enums.SaleOrderEnums;
import lombok.AccessLevel;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;

import java.util.ArrayList;
import java.util.List;

/**
 * 订单费用表
 */
@Data
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@EqualsAndHashCode(callSuper = true)
public class OrderExpensesBill extends AbstractSimpleAggregate<Long> {

  /**
   * 新建订单费用表
   *  @param sto
   */
  public OrderExpensesBill(OrderExpensesBillSto sto) {
    ValidationUtils.validate(sto);
    Wrapper wrapper = Wrapper.build().append(Restrictions.eq("sourceId",sto.getSourceId())).append(Restrictions.eq("orderType",sto.getOrderType()));
    OrderExpensesBillRepository orderExpensesBillRepository = (OrderExpensesBillRepository) SpringContextUtils.getBean(OrderExpensesBillRepository.class);
    if (orderExpensesBillRepository.getCount(wrapper) > 0) {
      throw new BusinessException("该订单已生成费用表，新建费用失败！");
    }
    super.initDefault();
    this.sourceId = sto.getSourceId();
    this.sourceCode = sto.getSourceCode();
    this.orderType = sto.getOrderType();
    this.brokerageId = sto.getBrokerageId();
    this.businessEntityId = sto.getBusinessEntityId();
    this.state = OrderExpensesBillEnums.State.UN_CONFIRM.getStatus();
    this.items = new ArrayList<>();
    sto.getItems().forEach(item -> {
      OrderExpensesBillItem orderExpensesBillItem = new OrderExpensesBillItem(item);
      orderExpensesBillItem.setOrderType(orderType);
      this.items.add(orderExpensesBillItem);
    });
  }

  /**
   * 修改订单费用表
   * @param mto
   */
   public void modify(OrderExpensesBillMto mto) {
      if (this.state.equals(OrderExpensesBillEnums.State.CONFIRM.getStatus())) {
        throw new BusinessException("费用单已确认，请取消后再修改！");
      }
      ValidationUtils.validate(mto);
      this.lastUpdateTimeStamp = System.currentTimeMillis();
      this.items = new ArrayList<>();
      mto.getItems().forEach(item -> {
         OrderExpensesBillItem orderExpensesBillItem = new OrderExpensesBillItem(item);
         orderExpensesBillItem.setOrderType(orderType);
         this.items.add(orderExpensesBillItem);
       });
   }

  /**
   * 确认订单费用生效
   * @param confirmTimeStamp
   */
  public void confirm(Long confirmTimeStamp) {
    if (!this.state.equals(OrderExpensesBillEnums.State.UN_CONFIRM.getStatus())) {
      throw new BusinessException("订单不是未确认状态，确认失败！");
    }
    switch (this.orderType) {
      //查找销售单状态
      case 1:
        SaleOrderReadRepository saleOrderReadRepository = (SaleOrderReadRepository) SpringContextUtils.getBean("saleOrderRepositoryImpl");
        SaleOrder saleOrder = saleOrderReadRepository.getById(this.sourceId);
        //如果订单未签收 则不允许确认费用单
        if (SaleOrderEnums.CollectState.LOGISTICS_UN_COLLECT.getStatus().equals(saleOrder.getCollectState())) {
          throw new BusinessException("销售单"+saleOrder.getCode()+"未签收，费用确认失败！");
        }
        break;
        //查找采购单状态
      case 2:
        PurchaseOrderReadRepository purchaseOrderReadRepository = (PurchaseOrderReadRepository) SpringContextUtils.getBean("purchaseOrderRepositoryImpl");
        PurchaseOrder purchaseOrder = purchaseOrderReadRepository.getById(this.sourceId);
        if (PurchaseOrderEnums.CollectState.LOGISTICS_UN_COLLECT.equals(purchaseOrder.getCollectState())) {
          throw new BusinessException("采购单"+purchaseOrder.getCode()+"未签收，费用确认失败！");
        }
    }

    this.state = OrderExpensesBillEnums.State.CONFIRM.getStatus();
    this.confirmTimeStamp = confirmTimeStamp == null ? System.currentTimeMillis() : confirmTimeStamp;
   }
  /**
   * 取消订单费用生效
   */
  public void cancel() {
    if (!this.state.equals(OrderExpensesBillEnums.State.CONFIRM.getStatus())) {
      throw new BusinessException("订单不是已确认状态，取消失败！");
    }
    this.state = OrderExpensesBillEnums.State.UN_CONFIRM.getStatus();
    this.confirmTimeStamp = null;
   }
  /**
   * 删除订单费用表
   */
  public void destory() {
    if (!this.state.equals(OrderExpensesBillEnums.State.UN_CONFIRM.getStatus())) {
      throw new BusinessException("订单不是未确认状态，删除失败！");
    }
    this.items = null;
   }

  /**
   * 原始单id
   */
  private Long sourceId;
  /**
   * 原始单编号
   */
  private String sourceCode;
  /**
   * 归属端id
   */
  private Long businessEntityId;
  /**
   * 原始单类型(1：销售单、2：采购单)
   */
  private Short orderType;
  /**
   * 状态（0：未确认 1：已确认）
   */
  private Short state;
  /**
   * 录单人id
   */
  private Long brokerageId;
  /**
   * 确认日期
   */
  private Long confirmTimeStamp;
  /**
   * 订单费用明细
   */
  private List<OrderExpensesBillItem> items;

}
